<template>
  <div :class="inputClass">
    <div v-if="label" class="mb-2">{{ label }}</div>
    <div class="input-field">
      <textarea
        v-if="type === 'textarea'"
        ref="inputRef"
        v-model="value"
        :placeholder="placeholder"
        :disabled="disabled"
        :readonly="readonly"
        :rows="rows"
        :maxlength="maxlength"
        @focus="handleFocus"
        @blur="handleBlur"
        class="input-textarea"
      ></textarea>
      <input
        v-else
        ref="inputRef"
        v-model="value"
        :type="type"
        :placeholder="placeholder"
        :disabled="disabled"
        :readonly="readonly"
        :maxlength="maxlength"
        @focus="handleFocus"
        @blur="handleBlur"
        class="input-control"
      />
      <div v-if="showClear" class="input-clear" @click="handleClear">
        <span class="iconfont icon-baseline-close-px"></span>
      </div>
      <div v-if="iconName" class="input-clear" @click="handleClick">
        <span class="iconfont" :class="iconName"></span>
      </div>
    </div>
    <div class="input-footer">
      <div v-if="error" class="input-error-message">{{ error }}</div>
      <div v-if="showWordLimit && maxlength" class="input-word-limit">
        {{ value ? value.length : 0 }}/{{ maxlength }}
      </div>
    </div>
  </div>
</template>
  
<script setup lang="ts"> 
import { defineProps, defineEmits, ref, computed } from 'vue';
const props = defineProps({
    modelValue: [String, Number],
    label: String,
    placeholder: String,
    type: {
      type: String,
      default: 'text'
    },
    error: String,
    clearable: Boolean,
    disabled: Boolean,
    readonly: Boolean,
    maxlength: [String, Number],
    showWordLimit: Boolean,
    rows: {
      type: [String, Number],
      default: 3
    },
    iconName: String
});
const emit = defineEmits(['update:modelValue', 'blur', 'focus', 'clear', 'handleClick'])
  
const isFocused = ref(false)
const inputRef = ref(null)

const value = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

const showClear = computed(() => {
  return props.clearable && !props.disabled && !props.readonly && value.value
})

const handleClear = () => {
  emit('update:modelValue', '')
  emit('clear')
  inputRef.value.focus()
}

const handleFocus = (e:any) => {
  isFocused.value = true
  emit('focus', e)
}

const handleBlur = (e:any) => {
  isFocused.value = false
  emit('blur', e)
}
const handleClick = (e:any) => {
  emit('handleClick', e)
}
const inputClass = computed(() => {
  return {
    'input-wrapper': true,
    'input-focused': isFocused.value,
    'input-error': !!props.error,
    'input-disabled': props.disabled,
    'input-readonly': props.readonly
  }
})
</script>
  
<style lang="scss" scoped>
.input-field {
  position: relative;
}
input, textarea {
  width: 100%;
  padding: 16px;
  background-color: #222;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  color: #fff;
  box-sizing: border-box;
}
input::placeholder, textarea::placeholder {
  color: #666;
}
.input-control:disabled,
.input-textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.input-clear {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #c8c9cc;
  cursor: pointer;
  font-size: 16px;
  transition: color 0.2s;
  z-index: 1;
}
.input-clear:hover {
  color: #969799;
}
.input-footer {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
}

.input-error-message {
  font-size: 12px;
  color: #ee0a24;
  text-align: left;
  flex: 1;
}

.input-word-limit {
  font-size: 12px;
  color: #969799;
  text-align: right;
}
</style>